package com.zmn.oms.third.jd_huadi.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.jd.open.api.sdk.DefaultJdClient;
import com.jd.open.api.sdk.JdClient;
import com.jd.open.api.sdk.domain.jjfw.OutinterfaceCloseorderService.response.close.ColseOrder;
import com.jd.open.api.sdk.domain.jjfw.RequestOrderService.response.search.FwTast;
import com.jd.open.api.sdk.request.jjfw.*;
import com.jd.open.api.sdk.response.jjfw.*;
import com.zmn.base.common.data.common.dro.area.AreaDRO;
import com.zmn.base.common.data.dubbo.interfaces.area.AreaListRemoteService;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.constant.StatusConsts;
import com.zmn.common.dictionary.GlobalDict;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.consts.GateTypeConsts;
import com.zmn.manager.redis.RedisManager;
import com.zmn.oms.business.interfaces.baidumap.BaiduMapBService;
import com.zmn.oms.business.interfaces.notifylog.OrderNotifyLogBService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.constant.RedisKeyConsts;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.common.utils.HttpUtil;
import com.zmn.oms.model.bo.order.OrderBO;
import com.zmn.oms.model.dto.baidumap.LngLatLocation;
import com.zmn.oms.model.dto.factory.OrderFactoryDTO;
import com.zmn.oms.model.dto.order.proxy.CancelOrderDTO;
import com.zmn.oms.model.dto.order.zmn.FactoryNewOrderDTO;
import com.zmn.oms.model.entity.notifylog.OrderNotifyLog;
import com.zmn.oms.model.entity.order.OrderExtend;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.entity.work.OrderWorkLogChange;
import com.zmn.oms.model.vo.work.ZsOrderWorkVO;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.order.OrderExtendService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.third.base.util.MasterPhoneUtil;
import com.zmn.oms.third.guomei.GmqxConsts;
import com.zmn.oms.third.jd_huadi.JdHuadiConsts;
import com.zmn.oms.third.jd_huadi.JdHuadiTokenConfig;
import com.zmn.oms.third.jd_huadi.service.JdHuadiService;
import com.zmn.oms.zmn.business.interfaces.proxy.ProxyOrderBService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkQueryBService;
import com.zmn.oms.zmn.business.interfaces.work.autoflow.WorkFlowContextBService;
import com.zmn.oms.zmn.normal.business.interfaces.order.FactoryOrderBService;
import io.netty.util.internal.StringUtil;
import org.apache.dubbo.config.annotation.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;

/**
 * 类描述：京东华帝对接接口实现
 *
 * @author XieWenBing
 * @date 2020/05/21 14:20
 */
@Service
public class JdHuadiServiceImpl implements JdHuadiService {

    private static final Logger logger = LoggerFactory.getLogger(JdHuadiServiceImpl.class);

    @Autowired
    protected ZsOrderWorkQueryBService zsOrderWorkQueryBService;
    @Autowired
    protected FactoryOrderBService factoryOrderBService;
    @Autowired
    protected ProxyOrderBService proxyOrderBService;
    @Autowired
    protected WorkFlowContextBService workFlowContextBService;
    @Autowired
    protected OrderWorkService orderWorkService;
    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    protected OrderNotifyLogBService orderNotifyLogBService;
    @Autowired
    protected OrderExtendService orderExtendService;
    @Autowired
    private BaiduMapBService baiduMapBService;

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    protected AreaListRemoteService areaListRemoteService;

    @Resource
    private RedisManager redisManager;

    /**
     * 从京东平台拉取工单任务列表
     */
    @Override
    public void pullOrderList(){

        // 创建JdClient接口类
        JdClient jdClient = this.getJdClient();
        if (Objects.isNull(jdClient)) {
            return;
        }

        // 创建HomefwTaskSearchRequest接口类
        HomefwTaskSearchRequest taskSearchRequest = new HomefwTaskSearchRequest();
        if (Objects.isNull(taskSearchRequest)) {
            logger.error("[{}]拉取订单失败：new HomefwTaskSearchRequest is null",JdHuadiConsts.CHANNEL_NAME);
            return;
        }

        // 设置参数
        taskSearchRequest.setPageSize(JdHuadiConsts.PULL_ORDER_PAGE_SIZE);
        taskSearchRequest.setVenderCode("");

        HomefwTaskSearchResponse taskSearchResponse = null;

        // 循环拉取工单
        for (int pullPage = 0; pullPage < JdHuadiConsts.PULL_ORDER_MAX_PAGE; pullPage++) {

            taskSearchRequest.setPage(pullPage+1);

            // 拉取订单
            try {
                taskSearchResponse = jdClient.execute(taskSearchRequest);
            } catch (Exception exception) {
                logger.error("[{}]拉取订单异常：[{}]",JdHuadiConsts.CHANNEL_NAME,exception.getMessage());
                return;
            }

            // 处理拉取工单列表回应消息
            if (Objects.isNull(taskSearchResponse) || Objects.isNull(taskSearchResponse.getResultInfo())) {
                logger.error("[{}]拉取订单失败：HomefwTaskSearchResponse or ResultInfo null",JdHuadiConsts.CHANNEL_NAME);
                return;
            }

            // 判断返回code
            Integer resultCode = Optional.ofNullable(taskSearchResponse.getResultInfo().getResultCode()).orElse(JdHuadiConsts.JD_HUADI_RESPONSE_FAILED_CODE);
            if (!Objects.equals(resultCode,JdHuadiConsts.JD_HUADI_RESPONSE_SUCCESS_CODE)) {
                logger.error("[{}]拉取订单失败：[{}]",JdHuadiConsts.CHANNEL_NAME,Optional.ofNullable(taskSearchResponse.getResultInfo().getErrMsg()).orElse("返回错误"));
                return;
            }

            // 处理任务工单列表
            if (CollectionUtils.isEmpty(taskSearchResponse.getResultInfo().getFwTastList())) {
                logger.error("[{}]拉取订单列表为空，停止拉取工单任务",JdHuadiConsts.CHANNEL_NAME);
                return;
            }

            // 任务工单获取成功后回传
            StringBuilder orderNos = new StringBuilder();
            taskSearchResponse.getResultInfo().getFwTastList().forEach(fwTast -> {
                if (Objects.nonNull(fwTast) && !StringUtils.isEmpty(fwTast.getOrderNo())) {
                    orderNos.append(fwTast.getOrderNo()).append(",");
                }
            });

            this.syncPushHandleState(orderNos.toString());
            logger.info("[{}]拉取订单列表：[{}]",JdHuadiConsts.CHANNEL_NAME,orderNos);

            // 创建订单
            taskSearchResponse.getResultInfo().getFwTastList().forEach(fwTast -> this.processPullOrderSearchTask(fwTast));
        }
    }

    /**
     * 从京东平台拉取取消的工单任务
     */
    @Override
    public void pullCancelOrder(){

        // 创建JdClient接口类
        JdClient jdClient = this.getJdClient();
        if (Objects.isNull(jdClient)) {
            return;
        }

        // 创建HomefwTaskCloseRequest接口类
        HomefwTaskCloseRequest taskCloseRequest = new HomefwTaskCloseRequest();
        if (Objects.isNull(taskCloseRequest)) {
            logger.error("[{}]拉取用户取消订单失败：new HomefwTaskCloseRequest is null",JdHuadiConsts.CHANNEL_NAME);
            return;
        }

        // 设置参数，开始时间为当前时间的20分钟前，结束时间为当前时间的5分钟前
        Long timeStart = DateUtil.getNow().getTime() - 20 * 60 * 1000;
        Date dateCalc = new Date();
        dateCalc.setTime(timeStart);
        taskCloseRequest.setBeginDate(DateUtil.dateFormatToString(dateCalc,"yyyy-MM-dd HH:mm:ss"));
        dateCalc.setTime(timeStart + 15 * 60 * 1000);
        taskCloseRequest.setEndDate(DateUtil.dateFormatToString(dateCalc,"yyyy-MM-dd HH:mm:ss"));

        taskCloseRequest.setPageSize(JdHuadiConsts.PULL_ORDER_PAGE_SIZE);
        taskCloseRequest.setVenderCode("");
        taskCloseRequest.setOrderNo("");

        HomefwTaskCloseResponse taskCloseResponse = null;

        // 循环拉取工单
        for (int pullPage = 0; pullPage < JdHuadiConsts.PULL_ORDER_MAX_PAGE; pullPage++) {

            taskCloseRequest.setPage(pullPage+1);

            // 拉取订单
            try {
                taskCloseResponse = jdClient.execute(taskCloseRequest);
            } catch (Exception exception) {
                logger.error("[{}]拉取用户取消订单异常：[{}]",JdHuadiConsts.CHANNEL_NAME,exception.getMessage());
                return;
            }

            // 处理拉取工单列表回应消息
            if (Objects.isNull(taskCloseResponse) || Objects.isNull(taskCloseResponse.getResultInfo())) {
                logger.error("[{}]拉取用户取消订单失败：HomefwTaskCloseResponse or ResultInfo null",JdHuadiConsts.CHANNEL_NAME);
                return;
            }

            // 判断返回code
            Integer resultCode = Optional.ofNullable(taskCloseResponse.getResultInfo().getResultCode()).orElse(JdHuadiConsts.JD_HUADI_RESPONSE_FAILED_CODE);
            if (!Objects.equals(resultCode,JdHuadiConsts.JD_HUADI_RESPONSE_SUCCESS_CODE)) {
                logger.error("[{}]拉取用户取消订单失败：[{}]",JdHuadiConsts.CHANNEL_NAME,Optional.ofNullable(taskCloseResponse.getResultInfo().getErrMsg()).orElse("返回错误"));
                return;
            }

            // 处理任务工单列表
            if (CollectionUtils.isEmpty(taskCloseResponse.getResultInfo().getCloseOrderList())) {
                logger.error("[{}]拉取用户取消订单列表为空，停止拉取取消工单任务",JdHuadiConsts.CHANNEL_NAME);
                return;
            }

            StringBuilder orderNos = new StringBuilder();
            taskCloseResponse.getResultInfo().getCloseOrderList().forEach(closeOrder -> {
                if (Objects.nonNull(closeOrder) && !StringUtils.isEmpty(closeOrder.getOrderNo())) {
                    orderNos.append(closeOrder.getOrderNo()).append(",");
                }
            });

            logger.info("[{}]拉取用户取消订单列表：[{}]",JdHuadiConsts.CHANNEL_NAME,orderNos);

            taskCloseResponse.getResultInfo().getCloseOrderList().forEach(closeOrder -> this.processPullCloseOrder(closeOrder));
        }
    }

    /**
     * 处理拉取的任务工单
     */
    protected void processPullOrderSearchTask(FwTast fwTast) {

        if (Objects.isNull(fwTast)) {
            return;
        }

        // 判断渠道工单
        String outerId = fwTast.getOrderNo();
        if (StringUtil.isNullOrEmpty(outerId)) {
            logger.error("【{}】创建订单失败-渠道工单号为空",JdHuadiConsts.CHANNEL_NAME);
            return ;
        }

        // 判断是否为重复工单号
        ZsOrderWorkVO orderWorkVO = zsOrderWorkQueryBService.findOrderWorkByOuterId(outerId, OrderConsts.CHANNEL_ID_JD_HUADI);
        if (Objects.nonNull(orderWorkVO) ) {
            logger.error("【{}】创建订单失败-订单号重复，订单已经存在",JdHuadiConsts.CHANNEL_NAME);
            return;
        }

        // 判断联系人电话
        if (StringUtil.isNullOrEmpty(fwTast.getUserMobile())) {
            logger.error("【{}】创建订单失败-没有用户电话",JdHuadiConsts.CHANNEL_NAME);
            return;
        }

        // 生成创建订单参数
        FactoryNewOrderDTO factoryNewOrderDTO = this.generateCreateOrderDTO(fwTast);
        if (Objects.isNull(factoryNewOrderDTO)) {
            return;
        }

        logger.info("【{}】工单任务创建订单：【{}】,【{}】", JdHuadiConsts.CHANNEL_NAME, JSON.toJSONString(fwTast),factoryNewOrderDTO);

        OrderWork orderWork = null;
        try {

            // 保存订单
            OrderBO orderBO = factoryOrderBService.insertOrder(factoryNewOrderDTO);
            orderWork = orderBO.getOrderWork();
            logger.info("【{}】保存订单成功 OrderId:[{}]",JdHuadiConsts.CHANNEL_NAME, orderWork.getOrderId());

        } catch (OmsBaseException omsBaseException) {
            logger.error("【{}】创建订单失败：{},{}", JdHuadiConsts.CHANNEL_NAME, omsBaseException.getMessage(),omsBaseException);
            return;
        } catch (Exception exception) {
            logger.error("【{}】创建订单失败：{},{}", JdHuadiConsts.CHANNEL_NAME, exception.getMessage(),exception);
            return;
        }

        // 保存扩展数据
        OrderExtend orderExtend = new OrderExtend();
        orderExtend.setExtId(orderWork.getOrderId());
        orderExtend.setOuterData(this.getOrderJsonString(fwTast));
        orderExtendService.updateOrderExtend(orderExtend);

        // 订单自动流转
        workFlowContextBService.asyncAutoFlow(orderWork.getOrderId(),orderWork.getWorkId());
    }

    /**
     * 根据渠道工单参数生成创建参数
     *
     * @param fwTast
     * @return CreateOrderDTO
     */
    protected FactoryNewOrderDTO generateCreateOrderDTO(FwTast fwTast) {

        FactoryNewOrderDTO factoryNewOrderDTO = new FactoryNewOrderDTO();
        if (Objects.isNull(factoryNewOrderDTO)) {
            return null;
        }

        // 渠道订单id
        factoryNewOrderDTO.setOuterId(fwTast.getOrderNo());

        // 预约时间
        factoryNewOrderDTO.setDutyTime(null);

        // 联系人
        factoryNewOrderDTO.setUserName(fwTast.getUserName());

        // 性别
        factoryNewOrderDTO.setGender(GlobalDict.GENDER_NO);

        // 电话
        // factoryNewOrderDTO.setTelephone(JdHuadiUtil.decrypt(fwTast.getUserMobile(),JdHuadiConsts.JD_HUADI_APP_KEY));
        factoryNewOrderDTO.setTelephone(fwTast.getUserMobile());

        // 地址
        // factoryNewOrderDTO.setAddress(JdHuadiUtil.decrypt(fwTast.getUserAddress(),JdHuadiConsts.JD_HUADI_APP_KEY));
        factoryNewOrderDTO.setAddress(fwTast.getUserAddress());

        // 街道
        factoryNewOrderDTO.setStreet(Optional.ofNullable(fwTast.getUserTown()).orElse(""));

        // 类型
        factoryNewOrderDTO.setType(OrderConsts.ORDER_TYPE_NEW);

        // 录入类型
        factoryNewOrderDTO.setInputType(OrderConsts.ORDER_INPUT_TYPE_API);

        // 操作者
        factoryNewOrderDTO.setOperator("系统");

        // 操作者id
        factoryNewOrderDTO.setOperatorId((long)OrderConsts.CHANNEL_ID_JD_HUADI);

        // 操作者类型
        factoryNewOrderDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_CHANNEL);

        // 备注
        factoryNewOrderDTO.setRemark(Optional.ofNullable(fwTast.getRemark()).orElse(""));

        // 平台标志
        factoryNewOrderDTO.setPlat(GlobalConsts.PLAT_MARK_YEYX);

        // 下单入口
        factoryNewOrderDTO.setReceiveEntranceId(GateTypeConsts.GATE_API_CUSTOM_MADE);

        // 保内
        factoryNewOrderDTO.setBizType(com.zmn.consts.GlobalConsts.BIZ_TYPE_F);

        // 下单方式
        factoryNewOrderDTO.setReceiverManner(OrderConsts.RECEIVE_MANNER_API);

        // 厂商信息
        OrderFactoryDTO orderFactory = new OrderFactoryDTO();

        // 厂商id
        orderFactory.setFactoryId(JdHuadiConsts.JD_HUADI_FACTORY_ID);

        // 厂商产品id
        orderFactory.setFcProductId(JdHuadiConsts.JD_HUADI_FACTORY_PRODUCT_ID);

        // 产品id
        orderFactory.setProductId(JdHuadiConsts.JD_HUADI_PRODUCT_ID);

        // 产品数量
        orderFactory.setFcProductNumber(1);

        // 厂商信息
        factoryNewOrderDTO.setOrderFactory(orderFactory);

        // 操作日志
        String areaName = fwTast.getUserProvince() + fwTast.getUserCity() + fwTast.getUserCounty() + Optional.ofNullable(fwTast.getUserTown()).orElse("");
        String operatorLogRemark = String.format(
                "京东华帝任务工单号：%s，下单时间：%s，京东订单号：%s，服务单类型：%s，商家名称：%s，品牌名称：%s，客户地址：%s %s，京东商家id：%s，订单指派时间：%s,客户留言：%s",
                fwTast.getOrderNo(), DateUtil.toString(fwTast.getCreateDate()),fwTast.getSaleOrderNo(),fwTast.getServiceTypeName(),
                fwTast.getCompanyName(),fwTast.getBrandName(),areaName,factoryNewOrderDTO.getAddress(),fwTast.getShopCode(),fwTast.getAppointDate().toString(),factoryNewOrderDTO.getRemark());

        // 城市id , 默认重庆
        Integer cityId = 500100;
        do {
            if (StringUtil.isNullOrEmpty(areaName)) {
                break;
            }

            // 查找经纬度
            LngLatLocation areaLocation = baiduMapBService.location(areaName);
            if (Objects.isNull(areaLocation)) {
                break;
            }

            // 经纬度查找区域信息
            ResponseDTO<AreaDRO> areaResponse = areaListRemoteService.getAreaByLatAndLng(Double.valueOf(areaLocation.getLng()), Double.valueOf(areaLocation.getLat()));
            if (Objects.isNull(areaResponse.getData())) {
                break;
            }

            cityId = areaResponse.getData().getParentId();

            Double longitude = Double.valueOf(areaResponse.getData().getLongitude());
            Double latitude = Double.valueOf(areaResponse.getData().getLatitude());

            // 设置经纬度
            factoryNewOrderDTO.setLongitude(longitude);
            factoryNewOrderDTO.setLatitude(latitude);

            operatorLogRemark = String.format("%s，经纬度：经纬度：%s,%s",operatorLogRemark,longitude,latitude);
        } while (false);

        // 设置城市ID
        factoryNewOrderDTO.setCityId(cityId);

        // 操作记录
        factoryNewOrderDTO.setOperatorLogRemark(operatorLogRemark);

        return factoryNewOrderDTO;
    }

    /**
     *  生成订单扩展数据
     *
     */
    protected String getOrderJsonString(FwTast fwTast) {

        if (Objects.isNull(fwTast)) {
            return "";
        }

        Map<String, String> mapOutData = Maps.newHashMap();
        mapOutData.put("outerOrderId",fwTast.getOrderNo());
        mapOutData.put("outerSaleOrderId",fwTast.getSaleOrderNo());
        mapOutData.put("outerCompanyName",fwTast.getCompanyName());
        mapOutData.put("userAddress",String.format("%s%s%s%s %s",fwTast.getUserProvince(),fwTast.getUserCity(),fwTast.getUserCounty(),
                Optional.ofNullable(fwTast.getUserTown()).orElse(""),fwTast.getUserAddress()));
        mapOutData.put("userPhone",fwTast.getUserMobile());

        return JSON.toJSONString(mapOutData);
    }

    /**
     * 任务工单获取成功后,将任务工单号返回给京东
     *
     * @param orderNos
     */
    protected void syncPushHandleState(String orderNos) {

        // 判断工单号是否正确
        if (StringUtils.isEmpty(orderNos)) {
            return;
        }

        logger.info("【{}】任务工单回传：{}", JdHuadiConsts.CHANNEL_NAME, orderNos);

        // 创建JdClient接口类
        JdClient jdClient = this.getJdClient();
        if (Objects.isNull(jdClient)) {
            return;
        }

        // 创建HomefwTaskPushHandleStatRequest接口类
        HomefwTaskPushHandleStatRequest pushHandleStatRequest = new HomefwTaskPushHandleStatRequest();
        if (Objects.isNull(pushHandleStatRequest)) {
            logger.error("[{}]任务工单回传失败：new HomefwTaskPushHandleStatRequest is null",JdHuadiConsts.CHANNEL_NAME);
            return;
        }

        // 设置参数
        pushHandleStatRequest.setOrderNos(orderNos);
        pushHandleStatRequest.setVenderCode("");

        HomefwTaskPushHandleStatResponse pushHandleStatResponse = null;
        try {
            pushHandleStatResponse = jdClient.execute(pushHandleStatRequest);
        } catch (Exception exception) {
            logger.error("[{}]任务工单回传异常：[{}]",JdHuadiConsts.CHANNEL_NAME,exception.getMessage());
            return;
        }

        // 处理拉取工单列表回应消息
        if (Objects.isNull(pushHandleStatResponse) || Objects.isNull(pushHandleStatResponse.getResultInfo())) {
            logger.error("[{}]任务工单回传失败：HomefwTaskPushHandleStatResponse or ResultInfo null",JdHuadiConsts.CHANNEL_NAME);
            return;
        }

        // 判断返回code
        Integer resultCode = Optional.ofNullable(pushHandleStatResponse.getResultInfo().getResultCode()).orElse(JdHuadiConsts.JD_HUADI_RESPONSE_FAILED_CODE);
        if (!Objects.equals(resultCode,JdHuadiConsts.JD_HUADI_RESPONSE_SUCCESS_CODE)) {
            logger.error("[{}]任务工单回传失败：[{}]",JdHuadiConsts.CHANNEL_NAME,Optional.ofNullable(pushHandleStatResponse.getResultInfo().getErrMsg()).orElse("返回错误"));
            return;
        }
    }

    /**
     * 将接单消息同步给渠道
     *
     * @param orderWorkLogChange
     */
    @Override
    public void syncAcceptOrder(OrderWorkLogChange orderWorkLogChange) {

        // 参数判断
        if (Objects.isNull(orderWorkLogChange)) {
            logger.error("[{}]同步接单失败：参数为空",JdHuadiConsts.CHANNEL_NAME);
            return;
        }

        // 判断是否已经同步接单
        if (this.findSuccessSyncResult(orderWorkLogChange.getOrderId(), OrderStatusConsts.ORDER_STATUS_INPUT)) {
            logger.error("[{}]已经同步接单，返回",JdHuadiConsts.CHANNEL_NAME);
            return;
        }

        // 判断外部订单单id
        String outerId = orderWorkLogChange.getOuterId();
        if (StringUtil.isNullOrEmpty(outerId)) {
            logger.error("[{}]同步接单失败：没有对应的外部订单Id",JdHuadiConsts.CHANNEL_NAME);
            return;
        }

        logger.info("【{}】同步接单：{}", JdHuadiConsts.CHANNEL_NAME, orderWorkLogChange.getOuterId());

        // 创建JdClient接口类
        JdClient jdClient = this.getJdClient();
        if (Objects.isNull(jdClient)) {
            return;
        }

        HomefwTaskAcceptRequest taskAcceptRequest = new HomefwTaskAcceptRequest();
        if (Objects.isNull(taskAcceptRequest)) {
            logger.error("[{}]同步订单完成失败：new HomefwTaskAcceptRequest is null",JdHuadiConsts.CHANNEL_NAME);
            return;
        }

        Boolean syncStatus = Boolean.FALSE;
        String  syncMessage;

        do {

            // 设置参数
            taskAcceptRequest.setHandleTime(DateUtil.toString(DateUtil.getNow(),"yyyy-MM-dd HH:mm:ss"));
            taskAcceptRequest.setOrderNo(outerId);
            taskAcceptRequest.setIsOneOrder(2);
            taskAcceptRequest.setAcceptType(2);
            taskAcceptRequest.setRemark("您的订单[言而有信]已接单");
            taskAcceptRequest.setVenderCode("");

            HomefwTaskAcceptResponse taskAcceptResponse = null;
            try {
                taskAcceptResponse = jdClient.execute(taskAcceptRequest);
            } catch (Exception exception) {
                syncMessage = String.format("[%s]同步接单异常：[%s]",JdHuadiConsts.CHANNEL_NAME,exception.getMessage());
                break;
            }

            // 处理拉取工单列表回应消息
            if (Objects.isNull(taskAcceptResponse) || Objects.isNull(taskAcceptResponse.getResultInfo())) {
                syncMessage = String.format("[%s]同步接单失败：taskAcceptResponse or ResultInfo null",JdHuadiConsts.CHANNEL_NAME);
                break;
            }

            // 判断返回code
            Integer resultCode = Optional.ofNullable(taskAcceptResponse.getResultInfo().getResultCode()).orElse(JdHuadiConsts.JD_HUADI_RESPONSE_FAILED_CODE);
            if (!Objects.equals(resultCode,JdHuadiConsts.JD_HUADI_RESPONSE_SUCCESS_CODE)) {
                syncMessage = String.format("[%s]同步接单失败：[%s]",JdHuadiConsts.CHANNEL_NAME,Optional.ofNullable(taskAcceptResponse.getResultInfo().getErrMsg()).orElse("返回错误"));
                break;
            }

            syncMessage = String.format("[%s]同步接单OK：外部渠道id[%s],订单id[%s]",JdHuadiConsts.CHANNEL_NAME,outerId,orderWorkLogChange.getOrderId());
            syncStatus = Boolean.TRUE;
        }while(false);

        // 失败或错误，则记录日志消息
        if (!syncStatus) {
            logger.error(syncMessage);
        } else {
            logger.info(syncMessage);
        }

        // 保存信息
        this.saveSyncResult(orderWorkLogChange,OrderStatusConsts.ORDER_STATUS_INPUT,syncMessage,syncStatus ? StatusConsts.STATUS_SUCCESS:StatusConsts.STATUS_ERROR);

    }

    /**
     * 将预约时间和领单师傅同步给渠道
     * @param orderWorkLogChange
     */
    @Override
    public void syncOrderDutyTimeAndMaster(OrderWorkLogChange orderWorkLogChange) {

        // 参数判断
        if (Objects.isNull(orderWorkLogChange)) {
            logger.error("[{}]同步预约/领单失败：参数为空",JdHuadiConsts.CHANNEL_NAME);
            return;
        }

        // 获取工单信息
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderWorkLogChange.getOrderId(),orderWorkLogChange.getWorkId());
        if (Objects.isNull(orderWork)) {
            logger.error("[{}]同步预约/领单失败：查不到对应的工单信息",JdHuadiConsts.CHANNEL_NAME);
            return;
        }

        // 判断预约时间
        Date dutyTime = orderWork.getDutyTime();
        String masterName = orderWork.getMasterName();
        String masterPhone = "15730252174";

        if (Objects.isNull(dutyTime) || StringUtil.isNullOrEmpty(masterName)) {
            logger.error("[{}]同步预约/领单未完成：预约时间或师傅为NULL",JdHuadiConsts.CHANNEL_NAME);
            return;
        }

        // 判断外部订单单id
        String outerId = orderWorkLogChange.getOuterId();
        if (StringUtil.isNullOrEmpty(outerId)) {
            logger.error("[{}]同步预约/领单失败：没有对应的外部订单Id",JdHuadiConsts.CHANNEL_NAME);
            return;
        }

        logger.info("【{}】同步预约/领单：{}", JdHuadiConsts.CHANNEL_NAME, orderWorkLogChange.getOuterId());

        // 创建JdClient接口类
        JdClient jdClient = this.getJdClient();
        if (Objects.isNull(jdClient)) {
            return;
        }

        HomefwTaskBookOndoorRequest taskBookOndoorRequest = new HomefwTaskBookOndoorRequest();
        if (Objects.isNull(taskBookOndoorRequest)) {
            logger.error("[{}]同步预约/领单失败：new HomefwTaskBookOndoorRequest is null",JdHuadiConsts.CHANNEL_NAME);
            return;
        }

        Boolean syncStatus = Boolean.FALSE;
        String  syncMessage = "";
        do {

            // 设置参数
            taskBookOndoorRequest.setOperateTime(DateUtil.toString(DateUtil.getNow(),"yyyy-MM-dd HH:mm:ss"));
            taskBookOndoorRequest.setOrderNo(outerId);
            taskBookOndoorRequest.setBookDate(DateUtil.toString(dutyTime,"yyyy-MM-dd HH:mm:ss"));
            taskBookOndoorRequest.setMasterName(String.format("%s工程师", masterName.substring(0,1)));
            taskBookOndoorRequest.setMasterPhone(
                    Optional.ofNullable(orderDetailService.findOrderDetailByKey(orderWork.getOrderId()))
                            .map(orderDetail -> {
                                if (Objects.equals(orderDetail.getBindStatus(), OrderConsts.BIND_STATUS_BIND)
                                        && org.apache.commons.lang3.StringUtils.isNotBlank(orderDetail.getBindTelephone())) {
                                    return orderDetail.getBindTelephone();
                                }
                                return null;
                            })
                            .orElse(MasterPhoneUtil.getSafeMasterPhone(orderWork.getCityId()))
            );
            taskBookOndoorRequest.setRemark(String.format("您的订单最新预约时间[%s]",taskBookOndoorRequest.getBookDate()));
            taskBookOndoorRequest.setVenderCode("");

            HomefwTaskBookOndoorResponse taskBookOndoorResponse = null;
            try {
                taskBookOndoorResponse = jdClient.execute(taskBookOndoorRequest);
            } catch (Exception exception) {
                syncMessage = String.format("[%s]同步预约/领单异常：[%s]",JdHuadiConsts.CHANNEL_NAME,exception.getMessage());
                break;
            }

            // 处理拉取工单列表回应消息
            if (Objects.isNull(taskBookOndoorResponse) || Objects.isNull(taskBookOndoorResponse.getResultInfo())) {
                syncMessage = String.format("[%s]同步预约/领单失败：taskAcceptResponse or ResultInfo null",JdHuadiConsts.CHANNEL_NAME);
                break;
            }

            // 判断返回code
            Integer resultCode = Optional.ofNullable(taskBookOndoorResponse.getResultInfo().getResultCode()).orElse(JdHuadiConsts.JD_HUADI_RESPONSE_FAILED_CODE);
            if (!Objects.equals(resultCode,JdHuadiConsts.JD_HUADI_RESPONSE_SUCCESS_CODE)) {
                syncMessage = String.format("[%s]同步预约/领单失败：[%s]",JdHuadiConsts.CHANNEL_NAME,Optional.ofNullable(taskBookOndoorResponse.getResultInfo().getErrMsg()).orElse("返回错误"));
                break;
            }

            syncMessage = String.format("[%s]同步预约/领单OK：渠道id[%s],订单id[%s]",JdHuadiConsts.CHANNEL_NAME,outerId,orderWorkLogChange.getOrderId());
            syncStatus = Boolean.TRUE;

        }while(false);


        // 失败或错误，则记录日志消息
        if (!syncStatus) {
            logger.error(syncMessage);
        } else {
            logger.info(syncMessage);
        }

        // 保存信息
        this.saveSyncResult(orderWorkLogChange,OrderStatusConsts.ORDER_STATUS_TAKE,syncMessage,syncStatus ? StatusConsts.STATUS_SUCCESS:StatusConsts.STATUS_ERROR);
    }

    /**
     * 将订单完成同步给渠道
     * @param orderWorkLogChange
     */
    @Override
    public void syncFinishOrder(OrderWorkLogChange orderWorkLogChange) {

        // 参数判断
        if (Objects.isNull(orderWorkLogChange)) {
            logger.error("[{}]同步订单完场失败：参数为空",JdHuadiConsts.CHANNEL_NAME);
            return;
        }

        // 判断外部订单单id
        String outerId = orderWorkLogChange.getOuterId();
        if (StringUtil.isNullOrEmpty(outerId)) {
            logger.error("[{}]同步订单完场失败：没有对应的外部订单Id",JdHuadiConsts.CHANNEL_NAME);
            return;
        }

        // 获取工单信息
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderWorkLogChange.getOrderId(),orderWorkLogChange.getWorkId());
        if (Objects.isNull(orderWork)) {
            logger.error("[{}]同步订单完场失败：查不到对应的工单信息",JdHuadiConsts.CHANNEL_NAME);
            return;
        }

        logger.info("【{}】同步订单完成状态：{}", JdHuadiConsts.CHANNEL_NAME, orderWorkLogChange.getOuterId());

        // 创建JdClient接口类
        JdClient jdClient = this.getJdClient();
        if (Objects.isNull(jdClient)) {
            return;
        }

        // 创建HomefwTaskFinishRequest接口类
        HomefwTaskFinishRequest taskFinishRequest = new HomefwTaskFinishRequest();
        if (Objects.isNull(taskFinishRequest)) {
            logger.error("[{}]同步订单完成失败：new HomefwTaskFinishRequest is null",JdHuadiConsts.CHANNEL_NAME);
            return;
        }

        Boolean syncStatus = Boolean.FALSE;
        String  syncMessage;
        do {

            // 设置参数
            Date finishTime = Optional.ofNullable(orderWork.getCompleteTime()).orElse(DateUtil.getNow());

            taskFinishRequest.setOrderNo(outerId);
            taskFinishRequest.setRemark("您的安装服务已完成，祝您生活愉快，谢谢");
            taskFinishRequest.setVenderCode("");
            taskFinishRequest.setOperateTime(DateUtil.toString(finishTime,"yyyy-MM-dd HH:mm:ss"));

            HomefwTaskFinishResponse taskFinishResponse = null;
            try {
                taskFinishResponse = jdClient.execute(taskFinishRequest);
            } catch (Exception exception) {
                syncMessage = String.format("[%s]同步订单完成异常：[%s]",JdHuadiConsts.CHANNEL_NAME,exception.getMessage());
                break;
            }

            // 处理拉取工单列表回应消息
            if (Objects.isNull(taskFinishResponse) || Objects.isNull(taskFinishResponse.getResultInfo())) {
                syncMessage = String.format("[%s]同步订单完成失败：taskFinishResponse or ResultInfo null",JdHuadiConsts.CHANNEL_NAME);
                break;
            }

            // 判断返回code
            Integer resultCode = Optional.ofNullable(taskFinishResponse.getResultInfo().getResultCode()).orElse(JdHuadiConsts.JD_HUADI_RESPONSE_FAILED_CODE);
            if (!Objects.equals(resultCode,JdHuadiConsts.JD_HUADI_RESPONSE_SUCCESS_CODE)) {
                syncMessage = String.format("[%s]同步订单完成失败：[%s]",JdHuadiConsts.CHANNEL_NAME,Optional.ofNullable(taskFinishResponse.getResultInfo().getErrMsg()).orElse("返回错误"));
                break;
            }

            syncMessage = String.format("[%s]同步订单完成，OK：渠道id[%s],订单id[%s]",JdHuadiConsts.CHANNEL_NAME,outerId,orderWorkLogChange.getOrderId());
            syncStatus = Boolean.TRUE;
        }while(false);

        // 失败或错误，则记录日志消息
        if (!syncStatus) {
            logger.error(syncMessage);
        } else {
            logger.info(syncMessage);
        }

        // 保存信息
        this.saveSyncResult(orderWorkLogChange,OrderStatusConsts.ORDER_STATUS_COMPLETE,syncMessage,syncStatus ? StatusConsts.STATUS_SUCCESS:StatusConsts.STATUS_ERROR);
    }

    /**
     * 处理拉取的用户取消的工单任务
     *
     * @param closeOrder
     */
    protected void processPullCloseOrder(ColseOrder closeOrder) {

        if (Objects.isNull(closeOrder) || StringUtils.isEmpty(closeOrder.getOrderNo())) {
            return;
        }

        ZsOrderWorkVO orderWorkVO = zsOrderWorkQueryBService.findOrderWorkByOuterId(closeOrder.getOrderNo(), OrderConsts.CHANNEL_ID_JD_HUADI);
        if (Objects.isNull(orderWorkVO)) {
            logger.error("[{}]取消订单错误:找不到对应的订单:[{}]",JdHuadiConsts.CHANNEL_NAME,closeOrder);
            return;
        }

        logger.info("【{}】取消订单：订单Id:[{}]，OuterId:[{}]，取消原因:[{}]，时间:[{}]", JdHuadiConsts.CHANNEL_NAME,
                orderWorkVO.getOrderId(), closeOrder.getOrderNo(), closeOrder.getReason(),DateUtil.getNow());

        // 取消订单
        CancelOrderDTO cancelOrderDTO = new CancelOrderDTO();
        cancelOrderDTO.setOrderId(orderWorkVO.getOrderId());
        cancelOrderDTO.setOuterId(closeOrder.getOrderNo());
        cancelOrderDTO.setChannelId(OrderConsts.CHANNEL_ID_JD_HUADI);
        cancelOrderDTO.setOperatorId((long)OrderConsts.CHANNEL_ID_JD_HUADI);
        cancelOrderDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_CHANNEL);
        cancelOrderDTO.setRemark(closeOrder.getReason());

        try {
            proxyOrderBService.cancelOrder(cancelOrderDTO);
        } catch (OmsBaseException omsBaseException) {
            logger.error("【{}】取消订单失败 消息:[{}]", GmqxConsts.CHANNEL_NAME, omsBaseException.getMessage());
        }
    }

    /**
     * 刷新accessToken的有效时间
     */
    @Override
    public void refreshAccessToken() {

        JdHuadiTokenConfig tokenConfig = this.getTokenConfig();
        if (Objects.isNull(tokenConfig)) {
            return;
        }

        long timeNow = DateUtil.getNow().getTime();
        // 如果有效时间-当前时间 大于 2小时 ，则不处理
        if ((tokenConfig.getExpiresTime()-timeNow) > 7200000) {
            return;
        }

        // 刷新token的有效时间
        String refreshUrl = String.format(JdHuadiConsts.JD_HUADI_APP_REFRESH_URL,JdHuadiConsts.JD_HUADI_APP_KEY,JdHuadiConsts.JD_HUADI_APP_SECRET,
                tokenConfig.getRefreshToken());
        String refreshResponse = "";
        try {
            refreshResponse = HttpUtil.httpsGet(refreshUrl);
        } catch (Exception exception) {
            logger.error("[{}]刷新Access token失败，HTTP异常：[{}]",JdHuadiConsts.CHANNEL_NAME,exception.getMessage());
            return;
        }

        JSONObject jsonObject = JSON.parseObject(refreshResponse);
        if (Objects.isNull(jsonObject)) {
            logger.error("[{}]刷新Access token失败，解析http返回信息：[{}]",JdHuadiConsts.CHANNEL_NAME,refreshResponse);
            return;
        }

        Integer repCode = Integer.valueOf(jsonObject.getString("code"));
        if (NumberUtil.isNotNullOrZero(repCode)) {
            logger.error("[{}]刷新Access token失败，返回code：[{}]",JdHuadiConsts.CHANNEL_NAME,repCode);
            return;
        }

        tokenConfig.setAccessToken(jsonObject.getString("access_token"));
        tokenConfig.setRefreshToken(jsonObject.getString("refresh_token"));
        Long expiresTime = Long.valueOf(jsonObject.getString("expires_in")) * 1000 + Long.valueOf(jsonObject.getString("time"));
        tokenConfig.setExpiresTime(expiresTime);

        // 保存token的信息
        String jsonTokenConfig = JSON.toJSONString(tokenConfig);
        if (Objects.nonNull(redisManager)) {
            redisManager.setex(RedisKeyConsts.JD_HUADI_TOKEN_REDIS_KEY,jsonTokenConfig,JdHuadiConsts.JD_HUADI_TOKEN_REDIS_TIMEOUT);
        }

        logger.info("[{}]刷新Access token成功，token信息：[{}]",JdHuadiConsts.CHANNEL_NAME,jsonTokenConfig);
    }

    /**
     * 获取与渠道对接的JdClient
     *
     * @return JdClient
     */
    protected JdClient getJdClient() {

        // 读取token
        JdHuadiTokenConfig tokenConfig = this.getTokenConfig();
        if (Objects.isNull(tokenConfig)) {
            logger.error("[{}]获得JdClient接口失败：access token读取失败",JdHuadiConsts.CHANNEL_NAME);
            return null;
        }

        // 创建JdClient接口类
        JdClient jdClient = new DefaultJdClient(JdHuadiConsts.JD_HUADI_APP_URL,tokenConfig.getAccessToken(),
                JdHuadiConsts.JD_HUADI_APP_KEY,JdHuadiConsts.JD_HUADI_APP_SECRET);
        if (Objects.isNull(jdClient)) {
            logger.error("[{}]获得JdClient接口失败：new JdClient is null",JdHuadiConsts.CHANNEL_NAME);
            return null;
        }

        return jdClient;
    }

    /**
     * 读取redis或配置，生成token信息
     *
     * @return JdHuadiTokenConfig
     */
    private JdHuadiTokenConfig getTokenConfig() {

        JdHuadiTokenConfig tokenConfig = null;
        do {

            if (Objects.isNull(redisManager)) {
                break;
            }

            // redis读取
            String jsonTokenConfig = redisManager.get(RedisKeyConsts.JD_HUADI_TOKEN_REDIS_KEY);
            if (StringUtils.isEmpty(jsonTokenConfig)) {
                break;
            }

            tokenConfig = JSON.parseObject(jsonTokenConfig,JdHuadiTokenConfig.class);
        }while(false);

        if (Objects.isNull(tokenConfig)) {

            tokenConfig = new JdHuadiTokenConfig();

            // 读取配置
            tokenConfig.setAccessToken(JdHuadiConsts.JD_HUADI_APP_ACCESS_TOKEN);
            tokenConfig.setRefreshToken(JdHuadiConsts.JD_HUADI_APP_REFRESH_TOKEN);
            tokenConfig.setExpiresTime(JdHuadiConsts.JD_HUADI_APP_REFRESH_TIMESTAMP);

            // 保存到redis
            String jsonTokenConfig = JSON.toJSONString(tokenConfig);
            if (Objects.nonNull(redisManager)) {
                redisManager.setex(RedisKeyConsts.JD_HUADI_TOKEN_REDIS_KEY,jsonTokenConfig,JdHuadiConsts.JD_HUADI_TOKEN_REDIS_TIMEOUT);
            }
        }

        return tokenConfig;
    }

    /**
     * 保存状态同步结果信息
     *
     * @param orderWorkLogChange
     * @param orderStatus
     * @param result
     */
    @SuppressWarnings("all")
    private void saveSyncResult(OrderWorkLogChange orderWorkLogChange, int orderStatus, String resultMessage, int resultStatus) {
        if (Objects.isNull(orderWorkLogChange)) {
            return;
        }

        OrderNotifyLog orderNotifyLog = new OrderNotifyLog();
        orderNotifyLog.setMqMsgKey(orderWorkLogChange.getMqMsgKey());
        orderNotifyLog.setOrderId(orderWorkLogChange.getOrderId());
        orderNotifyLog.setChannelId(orderWorkLogChange.getChannelId());
        orderNotifyLog.setOrderStatus(orderWorkLogChange.getStatus());
        orderNotifyLog.setOrderResultStatus(orderWorkLogChange.getResultStatus());
        orderNotifyLog.setNotifyStatus(String.valueOf(orderStatus));
        orderNotifyLog.setType(OrderConsts.ORDER_NOTIFY_TYPE_CHANGE);
        orderNotifyLog.setNotifyTime(DateUtil.getNow());
        orderNotifyLog.setNotifyResultMsg(String.format("[%s]-%s",
                OrderStatusConsts.getOrderStatusName(orderStatus), resultMessage));

        ResultDTO resultDTO = new ResultDTO();
        resultDTO.setStatus(resultStatus);
        resultDTO.setData(orderNotifyLog);

        orderNotifyLogBService.saveNotifyLog(resultDTO);
    }

    /**
     * 查询状态同步结果信息
     *
     * @param orderId
     * @param orderStatus
     * @return boolean
     */
    private Boolean findSuccessSyncResult(Long orderId, int orderStatus) {

        List<OrderNotifyLog> orderNotifyLogs = orderNotifyLogBService.listByOrderId(orderId);
        if (Objects.isNull(orderNotifyLogs)) {
            return Boolean.FALSE;
        }

        for (OrderNotifyLog item : orderNotifyLogs) {
            if (Objects.equals(String.valueOf(orderStatus), item.getNotifyStatus())
                    && Objects.equals(StatusConsts.STATUS_SUCCESS, item.getNotifyResultStatus())) {
                return Boolean.TRUE;
            }
        }

        return Boolean.FALSE;
    }

    /**
     * 测试
     *
     * @param args
     */
    public static void main(String[] args) {
        JdHuadiServiceImpl huadiService = new JdHuadiServiceImpl();
        huadiService.refreshAccessToken();
    }
}
